package com.yyl.appx.api

import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.paging.*
import com.squareup.moshi.JsonClass
import kotlinx.coroutines.flow.Flow
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory
import retrofit2.http.GET
import retrofit2.http.Query
import java.util.concurrent.TimeUnit


data class Repo(
    val id: Int,
    val name: String,
    val description: String?,
    val stargazers_count: Int
)


class RepoResponse(
    val items: List<Repo> = emptyList()
)

interface Api {

    @GET("/search/repositories?sort=stars&q=Android")
    suspend fun searchRepos(
        @Query("page") page: Int,
        @Query("per_page") perPage: Int
    ): RepoResponse

    companion object {
        private const val BASE_URL = "https://api.github.com"



        val api by lazy {
            val client = OkHttpClient.Builder()
            client.connectTimeout(15, TimeUnit.SECONDS)
                .readTimeout(15, TimeUnit.SECONDS)
//                .cache(Cache(BaseApplication.context.cacheDir, 100 * 1024 * 1024L))
                // .dns(OkHttpDns.getInstance(BaseApplication.context.applicationContext))
//                .addInterceptor(HeaderInterceptor())
//                .addInterceptor(HostInterceptor())
                .retryOnConnectionFailure(true)
                .hostnameVerifier { _, _ -> true } // 支持所有类型https请求
            Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(MoshiConverterFactory.create())
                .client(client.build())
                .build()
                .create(Api::class.java)
        }
    }
}

class RepoPagingSource : PagingSource<Int, Repo>() {
    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Repo> {
        return try {
            val page = params.key ?: 1 // set page 1 as default
            val pageSize = params.loadSize
            Log.i("api","PagingSource load")
            val repoResponse = Api.api.searchRepos(page, pageSize)
            val repoItems = repoResponse.items
            val prevKey = if (page > 1) page - 1 else null
            val nextKey = if (repoItems.isNotEmpty()) page + 1 else null
            Log.i("api","PagingSource size=${repoResponse.items.size}")
            LoadResult.Page(repoItems, prevKey, nextKey)
        } catch (e: Exception) {
            LoadResult.Error(e)
        }
    }

    override fun getRefreshKey(state: PagingState<Int, Repo>): Int? = null
}

object Repository {
    private const val PAGE_SIZE = 20
    fun getPagingData(): Flow<PagingData<Repo>> {
        return Pager(
            config = PagingConfig(PAGE_SIZE),
            pagingSourceFactory = { RepoPagingSource() }
        ).flow
    }

}
class MainViewModel : ViewModel() {

    fun getPagingData(): Flow<PagingData<Repo>> {
        //cachedIn 用于将服务器返回的数据在viewModelScope这个作用域内进行缓存，
        // 假如手机横竖屏发生了旋转导致Activity重新创建，Paging 3就可以直接读取缓存中的数据，而不用重新发起网络请求了
        return Repository.getPagingData().cachedIn(viewModelScope)
    }

}